#include "x_hiddevice.h"
#include "libusb/libusb.h"





/*------------------------------------------------------------------------------------------------------------------
Var
*/
bool X_HidDevice::isLibInit = false;    //标识libusb库是否做了初始化






/*
*********************************************************************************************************************

@ Brief  : 构造函数

@ Param  : NONE

@ Return : NONE

@ Author : YWJ

@ Date   : 2020-08-20 22:51:16

*********************************************************************************************************************
*/
X_HidDevice::X_HidDevice()
{
    dev_handle = nullptr;

    isDeviceOpen = false;
}


/*
*********************************************************************************************************************

@ Brief  : 打开一个指定的USB设备

@ Param  : NONE

@ Return : NONE

@ Author : YWJ

@ Date   : 2020-08-20 22:52:51

*********************************************************************************************************************
*/
bool X_HidDevice::OpenDevice(uint16_t PID , uint16_t VID)
{

    int ret;
    libusb_device* device;

    if(isDeviceOpen)
    {
        return false;
    }

    //打开设备
    dev_handle = libusb_open_device_with_vid_pid(NULL, VID , PID);

    if(dev_handle == NULL)
    {
        return false;
    }

    //判断设备驱动是否存在
    if(libusb_kernel_driver_active(dev_handle, 0) == 1)
    {

        //移除设备驱动
        if(libusb_detach_kernel_driver(dev_handle, 0) == 0)
        {
            //printf("Kernel Driver Detached!\n");
        }
        else
        {
            goto error;
        }
    }

    //邦定接口
    ret = libusb_claim_interface(dev_handle, 0);
    if(ret < 0)
    {
        goto error1;
    }


    isDeviceOpen = true;

    //拿到USB的设备地址，并记录下来
    device = libusb_get_device(dev_handle);
    Device_Addr = libusb_get_device_address(device);


    return true;

error1:
    ret = libusb_release_interface(dev_handle, 0);
error:
    libusb_close(dev_handle);
    return false;

}


/*
*********************************************************************************************************************

@ Brief  : 从设备中读取数据

@ Param  : NONE

@ Return : NONE

@ Author : YWJ

@ Date   : 2020-08-20 23:40:04

*********************************************************************************************************************
*/
void X_HidDevice::ReadData(uint8_t* RxData)
{

    if(isDeviceOpen == false)
    {
        return;
    }


    int ret;
    int transferred = 0;
    uint8_t ReadBuffer[65];


    ret = libusb_interrupt_transfer(dev_handle, 0x81, ReadBuffer, 65, &transferred, 0);



    memcpy(RxData , ReadBuffer , 64);

    if (ret != 0)
    {
        printf("failed to read \n");
    }

}

/*
*********************************************************************************************************************

@ Brief  : 向设备写入64字节的数据

@ Param  : RxData : 写入数据的指针

@ Return : NONE

@ Author : YWJ

@ Date   : 2020-08-20 23:39:03

*********************************************************************************************************************
*/
bool X_HidDevice::WriteData(uint8_t* RxData)
{
    if(isDeviceOpen == false)
    {
        return false;
    }

    int ret;
    int transferred = 0;
    uint8_t SendBuffer[65];
    memcpy(&SendBuffer[0] , RxData , 64);

    ret = libusb_interrupt_transfer(dev_handle, 0x02, SendBuffer, 65, &transferred, 10);
    if(ret==0 && transferred==65)
    {
       return true;
    }
    else
    {
        return false;
    }
}

/*
*********************************************************************************************************************

@ Brief  : 关闭设备

@ Param  : NONE

@ Return : NONE

@ Author : YWJ

@ Date   : 2020-08-20 23:38:28

*********************************************************************************************************************
*/
void X_HidDevice::Close(void)
{
    int ret;
    ret = libusb_release_interface(dev_handle, 0);
    if(ret != 0)
    {
        //错误
    }
    else
    {
        //OK
    }

    libusb_close(dev_handle);

    isDeviceOpen = false;
}



/*
*********************************************************************************************************************

@ Brief  : 初始化libusb库函数相关

@ Param  : NONE

@ Return : NONE

@ Author : YWJ

@ Date   : 2020-08-20 22:04:36

*********************************************************************************************************************
*/
void X_HidDevice::LibInit(void)
{
    int ret;

    //打开的情况下不重复打开
    if(isLibInit)
    {
        return;
    }

    //初始化库
    ret = libusb_init(NULL);
    if(ret < 0)
    {
        isLibInit = false;
        return;
    }
}


/*
*********************************************************************************************************************

@ Brief  : 相当于关闭库

@ Param  : NONE

@ Return : NONE

@ Author : YWJ

@ Date   : 2020-08-20 22:50:44

*********************************************************************************************************************
*/
void X_HidDevice:: LibExit(void)
{
    if(isLibInit)
    {
        //退出库
        libusb_exit(NULL);
    }
}


